<template>
  <view class="result-lottery-wrap">
    <!-- magic array -->
    <view
      class="magic-array"
      v-if="order.create"
      :class="order.show ? 'hide' : ''"
    >
      <view class="circle">
        <image class="magic-img" mode="heightFix" :src="magicArray" />
      </view>
    </view>

    <view
      class="spotlight"
      v-if="order.create"
      :class="order.show ? 'hide' : ''"
    >
      <image
        class="spotlight-img"
        :src="
          $IMG_URL + '/uploads/20230520/4f1689246b539ca2c50950f7e64e83f8.png'
        "
      />
    </view>
    <!-- 展示 -->
    <view v-if="order.summon">
      <block v-for="(col, col_key) in compartmentals" :key="col_key">
        <view
          class="content"
          :class="col.length < 4 ? 'once' : ''"
          v-if="active == col_key"
        >
          <lottery-item
            v-for="(item, index) in col"
            class="item"
            :key="index"
            :number="index + 1"
            :details="item"
            :show="true"
          ></lottery-item>
        </view>
      </block>
    </view>

    <!-- 底部按钮 -->
    <view class="bottom-btn" v-if="order.flop">
      <view
        class="pege-to btn"
        hover-class="hover-bubble"
        @tap="onClickOperate($event, 'next', {})"
        v-if="active < stage - 1"
      >
        <image class="bg-btn" :src="bgbtn" />
        <text class="">下一页</text>
      </view>
      <view
        class="open btn"
        hover-class="hover-bubble"
        @tap="onClickOperate($event, 'continue')"
        v-if="active == stage - 1 && number > 1"
      >
        <image class="bg-btn" :src="bgbtn" />
        <text class="">继续开奖</text>
      </view>
      <view
        class="given btn"
        hover-class="hover-bubble"
        @tap="onClickOperate($event, 'keep')"
        v-if="active == stage - 1 && number == 1"
      >
        <image class="bg-btn" :src="pinkbg" />
        <text class="">开心收下</text>
      </view>
    </view>
  </view>
</template>
<script>
/**
 * 动画展示
 * 1. 魔法阵生成
 * 2. 魔法阵召唤
 * 3. 奖品展示
 * 4. 翻牌
 */
// import magic from '../img/magic.png';
import bgbtn from '../img/btn-10.png';
import pinkbg from '../img/pink-10.png';
import tools from '@/shopro/utils/tools';
const _delay = tools.delayDither(50);
import { mapGetters } from 'vuex';
import { TEST_YFS_DATA_RESULT } from '../fullOpen_config';
import LotteryItem from './lottery-item.vue';
export default {
  // 建议 创建每个组件时 都添加name属性 标识组件名称
  name: '',
  components: { LotteryItem },
  props: {
    show: {
      type: Boolean,
      default: false,
    },
    number: {
      type: [String, Number],
      default: 0,
    },
    result: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      // 图片
      bgbtn,
      pinkbg,
      // magic,
      ///////
      // 当前展示
      active: 0,
      // 可显示数量
      capacity: 20,

      // 序列魔法阵
      magicArray: '',
      // 展示顺序
      order: {
        create: false,
        summon: false,
        show: false,
        flop: false,
      },
      // 定时器
      timer: {
        create: null,
        summon: null,
        show: null,
        flop: null,
      },
      // 是否跳过动画
      isSkip: false,
    };
  },
  // 计算属性 适配者模式
  computed: {
    ...mapGetters(['allSkip']),
    skip() {
      return this.allSkip || this.isSkip || false;
    },
    list() {
      // return this.result.list || [];
      return TEST_YFS_DATA_RESULT;
    },
    stage() {
      let excess = this.list.length % this.capacity;
      let stage = (this.list.length - excess) / this.capacity;
      excess > 0 ? stage++ : '';

      return stage;
    },
    compartmentals() {
      if (this.list.length <= this.capacity) {
        return [this.list];
      } else {
        let excess = this.list.length % this.capacity;
        let end = [];
        for (let i = 0; i < this.stage; i++) {
          if (i == this.stage - 1 && excess > 0) {
            end.push(
              this.list.slice(i * this.capacity, i * this.capacity + excess)
            );
          } else {
            end.push(
              this.list.slice(i * this.capacity, (i + 1) * this.capacity)
            );
          }
        }
        return end;
      }
    },
  },
  // 数据监听
  watch: {
    show(val) {
      if (val) {
        this.hideing();
        uni.showLoading({
          title: '正在加载',
          mask: true,
        });
        let show_timer = setTimeout(() => {
          clearTimeout(show_timer);
          uni.hideLoading();
          this.onSkip({
            success: () => {
              this.play();
            },
            fail: () => {},
          });
        }, 200);
      } else {
        this.hideing();
      }
    },
  },
  /**
   * 生命周期 类似 发布订阅者模式
   * 在实例初始化之前被调用
   */
  beforeCreate() {},
  // 在实例创建完成后被立即调用
  created() {},
  // 在挂载开始之前被调用
  beforeMount() {},
  // 挂载到实例上去之后调用。详见 注意：此处并不能确定子组件被全部挂载，如果需要子组件完全挂载之后在执行操作可以使用nextTick
  mounted() {
    this.loadingAnimation((res) => {
      this.magicArray = res;
    });
  },
  // 数据更新时调用，发生在虚拟 DOM 打补丁之前
  beforeUpdate() {},
  // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁，在这之后会调用该钩子
  updated() {},
  // 实例销毁之前调用。在这一步，实例仍然完全可用
  beforeDestroy() {},
  // Vue 实例销毁后调用。调用后，Vue 实例指示的所有东西都会解绑定，所有的事件监听器会被移除，所有的子实例也会被销毁。
  destroyed() {},
  methods: {
    /**
     *  页面点击事件 防抖
     * @param {Object} ev  $event
     * @param {String} name 执行名称
     * @param {Object} data 传值
     */
    onClickOperate(ev, name, data = {}) {
      _delay(() => {
        switch (name) {
          //继续
          case 'continue':
            this.$emit('continue', true);
            break;
          //收下
          case 'keep':
            this.$emit('keep', true);
            break;
          // 关闭弹窗
          case 'next':
            this.$emit('next', true);
            this.onNext(data);
            break;
        }
      });
    },
    onNext() {
      if (this.active < this.stage - 1) {
        this.active = this.active + 1;
      }
    },

    // 播放事件
    sequentialEvent() {
      let time_ = 4600;
      let summon = 600;
      let show = 1800;
      let flop = 2000;
      const callback = {
        create: (fn = () => {}) => {
          this.order.create = true;
          this.timer.create = setTimeout(() => {
            clearTimeout(this.timer.create);
            fn();
            // console.log('create');
            return callback.summon();
          }, time_);
        },
        summon: (fn = () => {}) => {
          this.timer.summon = setTimeout(() => {
            clearTimeout(this.timer.summon);
            fn();
            this.order.summon = true;
            // console.log('summon');
            return callback.show();
          }, summon);
        },
        show: (fn = () => {}) => {
          this.timer.show = setTimeout(() => {
            clearTimeout(this.timer.show);
            fn();
            this.order.show = true;
            // console.log('show');
            return callback.flop();
          }, show);
        },
        flop: (fn = () => {}) => {
          this.timer.flop = setTimeout(() => {
            clearTimeout(this.timer.flop);
            fn();
            this.order.flop = true;
            // console.log('flop');
          }, flop);
        },
      };
      return callback;
    },
    // 开始播放
    play() {
      const events = this.sequentialEvent();
      events.create();
    },
    hideing() {
      this.active = 0;

      //播放顺序
      this.order = {
        create: false,
        summon: false,
        show: false,
        flop: false,
      };
      this.isSkip = false;
      Object.keys(this.timer).forEach((item) => {
        const ele = this.timer[item];
        if (ele) {
          clearTimeout(ele);
        }
      });
    },
    // 跳过
    onSkip(ev = {}) {
      let { success = () => {}, fail = () => {} } = ev;
      if (this.skip) {
        this.order.show = true;
        this.order.flop = true;
        fail();
      } else {
        success();
      }
    },
    // 分割数
    partition() {
      let currentID = '1';
      let prefix = 'fullopen_img_';
      let name = 'fullopen_img_name';
      let num = 15;
      let arr = [];
      for (let i = 0; i < num; i++) {
        arr.push(`${prefix}${i + 1}`);
      }
      return {
        currentID,
        num,
        arr,
        name,
      };
    },
    //加载
    loadingAnimation(fn = () => {}) {
      wx.getStorageInfo({
        success: (info) => {
          console.log(info.currentSize / info.limitSize);
        },
      });

      const part = this.partition();
      let base_local = [];
      // 缓存id名
      let storage_animation_name = uni.getStorageSync(part.name) || '';
      // 拼接
      let len = part.arr.length;
      for (let i = 0; i < len; i++) {
        const item = part.arr[i];
        base_local.push(uni.getStorageSync(item));
      }
      // 检测 是否缺分段
      let check = base_local.every((item) => {
        return item;
      });

      if (check && storage_animation_name == part.currentID) {
        console.log('有缓冲');
        // 转字符串
        let base_ = base_local.join('');
        //转本地路径
        tools.base64src(base_, (res) => {
          fn(res);
        });
      } else {
        console.log('重新下载');
        // 清除 缓存
        this.clearLocalLoading(part.arr);
        // 下载视频
        this.download(
          this.$IMG_URL +
            '/uploads/20230529/e5946581075c8670f1b09d9901c37d4c.png'
        ).then((res) => {
          // 转64位
          let base = uni.arrayBufferToBase64(res.data);
          try {
            // 切割数
            let spilt_num = Math.ceil(base.length / part.num);
            //末位
            let last = 0;
            // 切割
            for (let i = 0; i < part.num; i++) {
              let str = '';

              if (spilt_num * i >= base.length) {
                last = base.length;
              } else {
                last = spilt_num * i + spilt_num;
              }
              str = base.slice(spilt_num * i, last);
              uni.setStorageSync(part.arr[i], str);
            }
            // id记录
            uni.setStorageSync(part.name, part.currentID);
          } catch (error) {
            console.log(error);
          }

          // 转本地路径
          tools.base64src(base, (res) => {
            fn(res);
          });
        });
      }
    },
    //清除缓存
    clearLocalLoading(data) {
      for (let i = 0; i < data.length; i++) {
        try {
          uni.removeStorageSync(data[i]);
        } catch (e) {
          // error
        }
      }
    },
    download(url) {
      return new Promise((resolve, reject) => {
        uni.request({
          url: url,
          responseType: 'arraybuffer',
          success: (res) => {
            resolve(res);
          },
          fail: () => {
            reject();
          },
        });
      });
    },
    mergeArrayBuffer(arrays) {
      let totalLen = 0;
      for (let arr of arrays) {
        totalLen += arr.byteLength;
      }
      let res = new Uint8Array(totalLen);
      let offset = 0;
      for (let earr of arrays) {
        for (let arr of [earr]) {
          let uint8Arr = new Uint8Array(arr);
          res.set(uint8Arr, offset);
          offset += arr.byteLength;
        }
      }
      return res.buffer;
    },
    close() {
      this.isSkip = false;
      if (!this.order.flop) return;
    },
  },
};
</script>
<style lang="scss" scoped>
view,
image {
  max-width: none;
}
.result-lottery-wrap {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100074;
  padding: 83rpx 25rpx 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-color: rgba(0, 0, 0, 0.9);

  perspective: 500;

  .magic-array {
    position: absolute;
    bottom: calc(50% - 50vw);
    left: 0;
    z-index: 1;
    width: 100vw;
    height: 100vw;
    overflow: hidden;
    animation: margic-group 0.6s linear 2.9s 1 normal forwards;
    &.hide {
      transition: all 1s;
      opacity: 0;
    }

    .circle {
      position: relative;
      width: 100vw;
      height: 100vw;
      overflow: hidden;
      -webkit-mask-image: radial-gradient(
        circle at 50% 50%,
        #000 38.333%,
        transparent 68.33%
      );
      animation: margic-rotate 10s linear 2.8s infinite normal forwards;
    }
    .magic-img {
      position: absolute;
      top: 0;
      left: 0;
      width: calc(100vw * 31);
      height: 100vw;
      animation: margic-array 3s steps(30, end) 0s 1 normal forwards;
    }
  }
  .spotlight {
    position: absolute;
    bottom: 0vw;
    left: calc(50% - 51vw);
    z-index: 2;
    height: 100vh;
    width: 100vw;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(180deg, #000 73.333%, transparent);

    &.hide {
      transition: all 1s;
      opacity: 0;
    }

    .spotlight-img {
      position: absolute;
      bottom: -46%;
      width: 100%;
      height: 146%;
      transform: scaleX(0);
      filter: hue-rotate(340deg);
      // margic-light
      animation: margic-light 1s linear 3.6s 1 normal forwards;
    }
  }
  .content.once {
    --s: 1.3;
  }
  .content {
    --s: 1;
    width: 100%;
    height: calc(100vh - 240rpx);
    /** grid */
    // display: grid;
    // grid-template-columns: repeat(auto-fill, 162rpx);
    // // grid-template-rows: repeat(auto-fill, 202rpx);
    // // 行列间距
    // column-gap: 15rpx;
    // row-gap: 15rpx;
    // justify-items: center;
    // align-content: center;
    // align-items: center;

    /* flex */
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    align-content: center;
    .item {
      margin: 0 7.5rpx 15rpx;
    }
    /*  */

    transform-style: preserve-3d;
    opacity: 0;
    animation: scale-up-bottom 0.6s linear 0s 1 normal forwards;
    .info,
    .draw-bg,
    .front,
    .back,
    .card {
      width: 162rpx;
      height: 202rpx;
    }
    .draw-bg {
      position: absolute;
      top: 0;
      left: 0;
    }
    .info,
    .card {
      position: relative;
      z-index: 1;
    }
    .card {
      perspective: 400px;
    }
    .info {
      .tag {
        position: absolute;
        top: 5rpx;
        left: 6rpx;
        font-size: 22rpx;
        font-weight: bold;
        color: #ffffff;
      }
      .level {
        position: absolute;
        top: 14rpx;
        right: 0rpx;
        transform: translate(-50%, -50%);
      }
      .cover {
        position: absolute;
        top: 14rpx;
        left: calc(50% - 76rpx);
        width: 152rpx;
        height: 152rpx;
      }

      .avatar {
        position: absolute;
        bottom: 44rpx;
        right: 3rpx;
        width: 35rpx;
        height: 35rpx;
        border: 4rpx solid #fff;
        background-color: #fff;
        border-radius: 15rpx 0rpx 15rpx 0rpx;
      }
      .name {
        position: absolute;
        bottom: 4rpx;
        left: 0;
        padding: 4rpx 6rpx;
        width: 100%;
        text-align: center;
        font-size: 22rpx;
        font-weight: 600;
        color: rgba(0, 0, 0, 1);
      }
    }
    .back,
    .front {
      position: absolute;
      top: 0;
      left: 0;
      backface-visibility: hidden;
      transform-style: preserve-3d;
    }
    .front {
      transform: rotateY(180deg);
    }
    .back {
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      .back-num {
        position: relative;
        z-index: 1;
        font-weight: 600;
        font-size: 26rpx;
        color: #fff;
      }
      .back-bg {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
      }
    }
  }
}

.bottom-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  bottom: 30rpx;
  left: 0;
  z-index: 10;
  padding: 0 50rpx;
  width: 100%;
  .btn {
    margin: 0 14rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    width: 188rpx;
    height: 87rpx;
    text {
      position: relative;
      font-size: 30rpx;
      font-weight: 800;
      color: #ffffff;
    }
    .bg-btn {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
  }
}

@keyframes scale-up-bottom {
  0% {
    opacity: 0;
    transform: translateY(400rpx) translateZ(-300rpx) rotateX(-10deg) scale(0.1);
    transform-origin: 50% 100%;
  }
  100% {
    opacity: 1;
    transform: translateY(0) translateZ(0) rotateX(0deg) scale(var(--s));
    transform-origin: 50% 50%;
  }
}
@keyframes margic-array {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-96.775%);
  }
}
@keyframes margic-group {
  0% {
    bottom: calc(50% - 50vw);
    transform: translate3d(0, 0, 0) rotateX(0) scale(1);
    transform-origin: 50% 100%;
  }
  100% {
    transform: translate3d(0, 0, 0) rotateX(110deg) scale(1.2);
    transform-origin: 50% 50%;
    bottom: -28vw;
  }
}
@keyframes margic-rotate {
  0% {
    transform: rotateZ(0);
    transform-origin: 50% 50%;
  }
  100% {
    transform: rotateZ(360deg);
    transform-origin: 50% 50%;
  }
}
@keyframes margic-light {
  0% {
    opacity: 1;
    transform: scaleX(0);
  }
  100% {
    opacity: 0.6;
    transform: scaleX(5);
  }
}
</style>
